/**
 *	Copyright (c) 2009, SpLib.net
 * 	All rights reserved.
  	
 * 	Author:6spring
 * 	About:绘图对象
*/

package SpLib.display
{
	import SpLib.std.stack;
	
	import flash.display.BitmapData;
	import flash.geom.ColorTransform;
	import flash.geom.Matrix;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.text.TextField;
	
	public class Graphics2D extends Graphics2DState
	{
		private static const s_ZeroPoint:Point = new Point();
		private var m_szState:SpLib.std.stack = new SpLib.std.stack();
		
		public function Graphics2D(img:flash.display.BitmapData = null)
		{
			super();
			
			m_DestImg = img;
			if(img!=null)
			{
				m_Rect.width = img.width;
				m_Rect.height = img.height;
				
				SetClip(new Rectangle(0,0,img.width,img.height));
			}
		}
		
		public function Create(w:int,h:int,bitmap:Boolean = true):void
		{
			m_szState.clear();
			
			m_Rect.width = w;
			m_Rect.height = h;
			if(bitmap)
			{
				m_DestImg = new flash.display.BitmapData(w,h,true,0x00000000);
			}
			
			SetTranslate(0,0);
			SetClip(new Rectangle(0,0,w,h));
		}

		/**
		 * 状态压栈
		 */
		public function PushState():void
		{
			m_szState.push(clone());
		}
		
		/**
		 * 状态退栈
		 */
		public function PopState():void
		{
			if(!m_szState.empty())
			{
				Copy(m_szState.pop());
			}
		}
		
		/**
		 * 设置画笔偏移
		 */
		public function SetTranslate(x:Number,y:Number):void
		{
			m_Trans.x = x;
			m_Trans.y = y;
		}
		
		/**
		 * 画笔偏移
		 */
		public function Translate(p:Point):void
		{
			m_Trans = m_Trans.add(p);
		}
		
		/**
		 * 设置裁剪矩形
		 */
		public function SetClip(rect:Rectangle):void
		{
			m_Clip = m_Rect.intersection(rect);
		}
		
		/**
		 * 裁剪
		 */
		public function Clip(rect:Rectangle):void
		{
			var clip:Rectangle = new Rectangle(rect.x + m_Trans.x,rect.y + m_Trans.y,rect.width,rect.height);
			m_Clip = m_Clip.intersection(clip);
		}
		
		/**
		 * 设置视口
		 */
		 public function SetViewPort(rect:Rectangle):void
		 {
		 	m_ViewPos = new Point(rect.x,rect.y);
			m_Clip = rect.clone();
			super.m_sType = TYPE_VIEW;
		 }
		
		/**
		 * 填充矩形
		 */
		public function FillRect(rect:Rectangle,color:uint):void
		{
			var destrect:Rectangle = new Rectangle(rect.x+m_Trans.x,rect.y+m_Trans.y,rect.width,rect.height);
			destrect = destrect.intersection(m_Clip);
			m_DestImg.fillRect(destrect,color);
		}
		
		/**
		 * 全透明填充
		 */
		public function Clear():void
		{
			m_DestImg.fillRect(m_Clip,0x00000000);
		}
		
		/**
		 * 填充
		 */
		public function Fill(color:uint):void
		{
			m_DestImg.fillRect(m_Clip,color);
		}		
		
		/**
		 * 初步偏移裁剪
		 */
		protected function _GetDrawRect(x:Number,y:Number,w:Number,h:Number):Rectangle
		{
			return m_Clip.intersection( new Rectangle(m_Trans.x+x,m_Trans.y+y,w,h) );
		}
		
		public function IsClip(x:Number,y:Number,w:Number,h:Number):Boolean
		{
			return !m_Clip.intersects(new Rectangle(x,y,w,h) );
		}
		
		public function RectIsClip(rect:Rectangle):Boolean
		{
			var clip:Rectangle = rect.clone();
			clip.x += m_Trans.x;
			clip.y += m_Trans.y;
			return !m_Clip.intersects(clip);
		}
		
		/**
		 * 获取图局部
		 */
		protected function _SubBitmapData(img:BitmapData,rect:Rectangle,x:Number,y:Number):BitmapData
		{
			var draw_rect:Rectangle = new Rectangle(x,y,rect.width,rect.height);
	
			//全包含	
			if(rect==img.rect && m_Clip.containsRect(draw_rect))
			{
				return img;
			}
			
			draw_rect = m_Clip.intersection(draw_rect);
			//完全不相交
			if(draw_rect.width<1||draw_rect.height<1)
			{
				return null;
			}
			
			draw_rect.x = rect.x;
			draw_rect.y = rect.y;
				
			//需要裁剪拷贝			
			if(x<m_Clip.x)
			{
				draw_rect.width += m_Clip.x - x;	
			}
			
			if(y<m_Clip.y)
			{
				draw_rect.height += m_Clip.y - y;
			}
			
			if(draw_rect.width<1||draw_rect.height<1)
			{
				return null;
			}
			
			var drawimg:flash.display.BitmapData = new flash.display.BitmapData(draw_rect.width,draw_rect.height,true,0x00000000);
			drawimg.copyPixels(img,draw_rect,s_ZeroPoint);
			return drawimg;
		}
			
		/**
		 * 画线
		 */
		public function Draw_Line(x1:int,y1:int,x2:int,y2:int,col:uint):void
		{
			var x:int = x1<x2?x1:x2;
			var y:int = y1<y2?y1:y2;
			var w:int = Math.abs(x1-x2);
			var h:int = Math.abs(y1-y2);
			w = Math.max(w,1);
			h = Math.max(h,1);
			
			if(IsClip(x,y,w,h))
			{
				return;	
			}

			var tmp:int;
			var flag:Boolean = Math.abs(y2-y1)>Math.abs(x2-x1);
			if(flag)
			{
				tmp = x1;
				x1 = y1;
				y1 = tmp
				
				tmp = x2;
				x2 = y2;
				y2 = tmp;
			}
			
			if(x1>x2)
			{
				tmp = x1;
				x1 = x2;
				x2 = tmp;
				
				tmp = y1;
				y1 = y2;
				y2 = tmp;
			}
			
			var dx:int = x2 - x1;
			var dy:int = Math.abs(y2 - y1);
			var error:int = -dx/2;
			var ystep:int = y1<y2?1:-1;
			
			y = y1;
			if(flag)
			{
				for(x=x1;x<=x2;x++)
				{
					m_DestImg.setPixel32(y,x,col);
					error += dy;
					if(error>0)
					{
						y += ystep;
						error = error - dx;
					}
				}
			}
			else
			{
				for(x=x1;x<=x2;x++)
				{
					m_DestImg.setPixel32(x,y,col);
					error += dy;
					if(error>0)
					{
						y += ystep;
						error = error - dx;
					}
				}
			}
		}
		
		public function Draw_RectBorder(col:uint,rect_src:Rectangle = null):void
		{
			if(rect_src==null)
			{
				rect_src = m_Clip.clone();
			}
			
			var rect_draw:Rectangle = m_Clip.intersection(rect_src);
			if(rect_draw==null)
			{
				return;
			}
			
			switch(super.m_sType)
			{
			case TYPE_VIEW:
			{
				rect_draw.x -= m_ViewPos.x;
				rect_draw.y -= m_ViewPos.y;
			}
			break;
			}
			
			var x:int,y:int;
			y = rect_draw.y;
			for(x=rect_draw.x;x<rect_draw.right;x++)
			{
				m_DestImg.setPixel32(x,y,col);
				m_DestImg.setPixel32(x,rect_draw.bottom-1,col);
			}
				
			x = rect_draw.x;
			for(y=rect_draw.y;y<rect_draw.bottom;y++)
			{
				m_DestImg.setPixel32(x,y,col);
				m_DestImg.setPixel32(rect_draw.right-1,y,col);
			}
		}
		
		/**
		 * 画标准菱形
		 */
		public function Draw_Diamond(col:uint,rect:Rectangle = null):void
		{
			if(rect==null)
			{
				rect = m_Rect.clone();
			}
		
			rect = m_Rect.intersection(rect);
			
			var per:Number = rect.width/rect.height;
			
			var x:int,y:int,begx:int,j:int,r:int;
			for(y=rect.y;y<rect.bottom;y++)
			{
				if(y<=rect.bottom/2)
				{
					begx = rect.width/2 - per*(y - rect.y);
				}
				else
				{
					begx = per*(y - rect.bottom/2);
				}
				
				for(x=begx;x<=(rect.width-begx);x++)
				{	
					m_DestImg.setPixel32(x,y,col);
				}
			}
		}
		
		/**
		 * 水平翻转
		 */
		public function Draw_HFlip(img:BitmapData,rect_src:Rectangle = null):void
		{
			if(rect_src==null)
			{
				rect_src = img.rect.clone();
			}
			
			var drawimg:flash.display.BitmapData = _SubBitmapData(img,rect_src,0,0);
			if(drawimg!=null)
			{
				var x:int,y:int;
				for(y=0;y<drawimg.height;y++)
				{
					for(x=0;x<drawimg.width;x++)
					{
						m_DestImg.setPixel32(drawimg.rect.width-x,y,drawimg.getPixel32(x,y));
					}
				}
			}
		}
		
		/**
		 * 垂直翻转
		 */
		public function Draw_VFlip(img:BitmapData,rect_src:Rectangle = null):void
		{
			if(rect_src==null)
			{
				rect_src = img.rect.clone();
			}
			
			var drawimg:flash.display.BitmapData = _SubBitmapData(img,rect_src,0,0);
			if(drawimg!=null)
			{
				var x:int,y:int;
				for(y=0;y<drawimg.height;y++)
				{
					for(x=0;x<drawimg.width;x++)
					{
						m_DestImg.setPixel32(x,drawimg.rect.height-y,drawimg.getPixel32(x,y));
					}
				}	
			}
		}
		
		/**
		 * 绘制文字
		 */
		 public function Draw_Text(txt:String,col:uint,x:int = 0,y:int = 0):void
		 {
		 	var pos:Point = new Point(m_Trans.x+x,m_Trans.y+y);
		 	
		 	var text:TextField = new TextField();
		 	text.textColor = col;
		 	text.background = false;
		 	text.backgroundColor
		 	text.autoSize = "left";
		 	text.text = txt;
		 	
		 	if(IsClip(pos.x,pos.y,text.width,text.height))
			{
				return;	
			}
		 	
		 	var img:BitmapData = new BitmapData(text.width,text.height,false,0x00000000);
		 	img.draw(text);
		 	
		 	var drawimg:flash.display.BitmapData = _SubBitmapData(img,img.rect,pos.x,pos.y);
		 	if(drawimg!=null)
		 	{
			 	m_DestImg.draw(drawimg,new flash.geom.Matrix(1,0,0,1,pos.x,pos.y));
			 }
		 }
		 
		 /**
		 * 标准贴图，覆盖，不管alpha
		 */
		public function Draw_Copy(
			img:BitmapData,
			x:Number = 0,y:Number = 0,
			rect_src:Rectangle = null,
			alphaimg:BitmapData = null,
			alphapoint:Point = null,
			mergeAlpha:Boolean = false):void
		{
			if(rect_src==null)
			{
				rect_src = img.rect.clone();
			}
			
			var pos:Point = new Point(m_Trans.x+x,m_Trans.y+y);
			
			if(IsClip(pos.x,pos.y,rect_src.width,rect_src.height))
			{
				return;	
			}
			
			var drawimg:flash.display.BitmapData = _SubBitmapData(img,rect_src,pos.x,pos.y);
			if(drawimg!=null)
			{
				switch(super.m_sType)
				{
				case TYPE_NORMAL:
				break;
				case TYPE_VIEW:
					pos = new Point(pos.x-m_ViewPos.x,pos.y-m_ViewPos.y);
				break;
				}
				
				m_DestImg.copyPixels(drawimg,drawimg.rect,pos,alphaimg,alphapoint,mergeAlpha);
			}
		}
		
		/**
		 * 标准贴图
		 */
		public function Draw_Normal(
			img:BitmapData,
			x:Number = 0,y:Number = 0,
			rect_src:Rectangle = null,
			colorTransform:flash.geom.ColorTransform=null,
			smoothing:Boolean = false):void
		{
			if(rect_src==null)
			{
				rect_src = img.rect.clone();
			}
			
			var pos:Point = new Point(m_Trans.x+x,m_Trans.y+y);
			
			if(IsClip(pos.x,pos.y,rect_src.width,rect_src.height))
			{
				return;	
			}
			
			var drawimg:flash.display.BitmapData = _SubBitmapData(img,rect_src,pos.x,pos.y);
			if(drawimg!=null)
			{
				var matrix:flash.geom.Matrix;
				switch(super.m_sType)
				{
				case TYPE_NORMAL:
					matrix = new flash.geom.Matrix(1,0,0,1,pos.x,pos.y);
				break;
				case TYPE_VIEW:
					matrix = new flash.geom.Matrix(1,0,0,1,pos.x-m_ViewPos.x,pos.y-m_ViewPos.y);
				break;
				}
				
				m_DestImg.draw(drawimg,matrix,colorTransform,null,null,smoothing);
			}
		}
		
		/**
		 * 标准alpha贴图
		 */
		public function Draw_Normal_Alpha(
			img:BitmapData,
			alpha:int,
			x:Number = 0,y:Number = 0,
			rect_src:Rectangle = null):void
		{
			if(alpha>=0xFF)
			{
				Draw_Normal(img,x,y,rect_src);
			}
			else
			{
				var ct:flash.geom.ColorTransform = new flash.geom.ColorTransform();
				ct.alphaMultiplier = alpha;
				ct.alphaMultiplier /= 0xFF;
				Draw_Normal(img,x,y,rect_src,ct);
			}
		}

		/**
		 * 贴图
		 */
		public function Draw_Scale(img:BitmapData,sx:Number,sy:Number,x:Number = 0,y:Number = 0):void
		{
			var matrix:flash.geom.Matrix = new flash.geom.Matrix(sx,0,0,sy,m_Trans.x+x,m_Trans.y+y);
			m_DestImg.draw(img,matrix);
		}
	}
}